package cyx.example.ddd.infrastructure.order.converter;

import cyx.example.ddd.domain.order.model.aggregate.Order;
import cyx.example.ddd.domain.order.model.entity.OrderItem;
import cyx.example.ddd.domain.order.model.valueobject.Money;
import cyx.example.ddd.infrastructure.order.entity.OrderDO;
import cyx.example.ddd.infrastructure.order.entity.OrderItemDO;
import org.springframework.stereotype.Component;

import java.util.Currency;
import java.util.stream.Collectors;

/**
 * 订单转换器
 * 负责在领域对象和数据对象之间进行转换
 */
@Component
public class OrderConverter {

    public OrderDO toData(Order order) {
        if (order == null) {
            return null;
        }

        OrderDO orderDO = new OrderDO();
        orderDO.setId(order.getId());
        orderDO.setUserId(order.getUserId());
        orderDO.setTotalAmount(order.getTotalAmount().getAmount());
        orderDO.setCurrency(order.getTotalAmount().getCurrency().getCurrencyCode());
        orderDO.setStatus(order.getStatus());
        orderDO.setCreatedAt(order.getCreatedAt());
        orderDO.setCancelReason(order.getCancelReason());

        orderDO.setOrderItems(order.getOrderItems().stream()
                .map(this::toData)
                .collect(Collectors.toList()));

        return orderDO;
    }

    public Order toDomain(OrderDO orderDO) {
        if (orderDO == null) {
            return null;
        }

        Order order = new Order(orderDO.getUserId(), Currency.getInstance(orderDO.getCurrency()));
        order.setId(orderDO.getId());

        // 添加订单项
        orderDO.getOrderItems().forEach(itemDO -> {
            Money unitPrice = new Money(itemDO.getUnitPrice(), Currency.getInstance(itemDO.getCurrency()));
            order.addOrderItem(itemDO.getProductId(), itemDO.getProductName(), unitPrice, itemDO.getQuantity());
        });

        // 设置状态
        switch (orderDO.getStatus()) {
            case PAID:
                order.pay();
                break;
            case CONFIRMED:
                order.pay();
                order.confirm();
                break;
            case SHIPPING:
                order.pay();
                order.confirm();
                order.startShipping();
                break;
            case COMPLETED:
                order.pay();
                order.confirm();
                order.startShipping();
                order.complete();
                break;
            case CANCELLED:
                order.cancel(orderDO.getCancelReason());
                break;
        }

        return order;
    }

    private OrderItemDO toData(OrderItem orderItem) {
        if (orderItem == null) {
            return null;
        }

        OrderItemDO orderItemDO = new OrderItemDO();
        orderItemDO.setId(orderItem.getId());
        orderItemDO.setProductId(orderItem.getProductId());
        orderItemDO.setProductName(orderItem.getProductName());
        orderItemDO.setUnitPrice(orderItem.getUnitPrice().getAmount());
        orderItemDO.setCurrency(orderItem.getUnitPrice().getCurrency().getCurrencyCode());
        orderItemDO.setQuantity(orderItem.getQuantity());
        orderItemDO.setTotalPrice(orderItem.getTotalPrice().getAmount());

        return orderItemDO;
    }
}